package top.yudoge.dogeeditor.llm.rewrite

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import top.yudoge.dogeeditor.commons.cache.Cache
import top.yudoge.dogeeditor.commons.utils.convertList
import top.yudoge.dogeeditor.db.api.DataSourceMetaDataApi
import top.yudoge.dogeeditor.llm.objects.mro.TableMRO
import top.yudoge.dogeeditor.llm.task.TableEmbeddingTask
import top.yudoge.dogeeditor.llm.util.VectorUtils
import top.yudoge.dogeeditor.llm.util.tokenizer.Tokenizer

@Component
class TableInformationGetChainNode : TaskChainNode {


    @Autowired
    private lateinit var metaDataApi: DataSourceMetaDataApi

    @Autowired
    private lateinit var cache: Cache<String>

    @Autowired
    private lateinit var tokenizer: Tokenizer



    override fun process(ctx: ChainContext) {
        return
//        var possibleTableNames = getChainStore(ctx, TableNameExtractChainNode.TABLE_NAMES) as? Set<String>
//
//        sendReasoningCallback(ctx, "get table informations: ${possibleTableNames}")
//
//        if (possibleTableNames.isNullOrEmpty()) {
//            emitNext(ctx)
//            return
//        }
//
//        // convert possible table names to real table names(by embedding)
//        val realTableNames = getRealTableNames(ctx, possibleTableNames)
//        println("realTableNames: $realTableNames")
//
//        val realTableInfos = mutableListOf<TableMRO>()
//
//        for (tableName in realTableNames) {
//            var columns =
//                metaDataApi.getColumns(ctx.query.dataSourceIdentifier, ctx.query.databaseName, ctx.query.schemaName, tableName)
//            if (!columns.isNullOrEmpty()) {
//                var tableMRO = TableMRO(tableName, columns.convertList())
//                realTableInfos.add(tableMRO)
//            }
//        }
//
//        println("realTableInfos: $realTableInfos")
//        putChainStore(ctx, TABLE_INFO, realTableInfos)
//        emitNext(ctx)
//    }
//
//    fun getRealTableNames(ctx: ChainContext, possibleTableName: Set<String>): Set<String> {
//        if (possibleTableName.isNullOrEmpty()) {
//            return emptySet()
//        }
//        val dsName = ctx.query.dataSourceIdentifier
//        val dbName = ctx.query.databaseName
//        val schemaName = ctx.query.schemaName
//
//        val ( vocabulary, allEmbeddings ) = tableEmbeddingService.getTableEmbeddings(dsName, dbName, schemaName)
//        return possibleTableName.map {
//            var cachedTableName = cache.get(cacheKey(dsName, dbName, schemaName, it), String::class.java)
//            if (cachedTableName != null) {
//                cachedTableName
//            } else {
//                val embedding = TableEmbeddingTask.embedding(tokenizer, it, vocabulary)
//                var bestSimilarIndex = VectorUtils.bestSimilar(embedding, allEmbeddings.map { it.embedding })
//                if (bestSimilarIndex != -1) {
//                    allEmbeddings[bestSimilarIndex].tableName
//                } else {
//                    ""
//                }
//            }
//        }.filter { it.isNotBlank() }.toSet()
    }

    private fun cacheKey(dsName: String, dbName: String, schemaName: String, possibleTableName: String) =
        "dbtools:possible_table_name:$dsName:$dbName:$schemaName:$possibleTableName";

    companion object {
        const val TABLE_INFO = "tableInfo"
    }

}